package com.lab.forthreadpool;

import com.lab.NoobChain;

import java.security.*;
import java.security.spec.ECGenParameterSpec;
import java.util.ArrayList;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
 * @author weiwei
 */
public class Wallet {

    public PrivateKey privateKey;//私钥
    public PublicKey publicKey;//公钥

    public ConcurrentHashMap<String, TransactionOutput> UTXOs =
            new ConcurrentHashMap<String, TransactionOutput>();

    public Wallet() {
        generateKeyPair();
    }

    public void generateKeyPair() {
        try {
            KeyPairGenerator keyGen = KeyPairGenerator.getInstance("ECDSA", "BC");
            SecureRandom random = SecureRandom.getInstance("SHA1PRNG");
            ECGenParameterSpec ecSpec = new ECGenParameterSpec("prime192v1");
            // Initialize the key generator and generate a KeyPair
            keyGen.initialize(ecSpec, random); //256
            KeyPair keyPair = keyGen.generateKeyPair();
            // Set the public and private keys from the keyPair
            privateKey = keyPair.getPrivate();
            publicKey = keyPair.getPublic();

        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    /*
    NoobChain中查找属于自己的交易，然后求出自己的value总额，最后将属于自己的UTXO放到自己的UTXOs
     */
    public synchronized double getBalance() {
        double total = 0;
        for (Map.Entry<String, TransactionOutput> item : NoobChain.UTXOs.entrySet()) {
            TransactionOutput UTXO = item.getValue();
            if (UTXO.isMine(publicKey)) { //判断UTOXs是不是属于自己的
                UTXOs.put(UTXO.id, UTXO); //放到自己的UTXOs下面
                total += UTXO.value;
            }
        }
        return total;
    }

    /*
    生成交易类
     */
    public synchronized Transaction sendFunds(PublicKey _recipient, double value) {
        if (getBalance() < value) {
            System.out.println("#Not Enough funds to send transaction. Transaction Discarded.");
            return null;
        }
        ArrayList<TransactionInput> inputs = new ArrayList<TransactionInput>();

        //从钱包里取出适量的output交易放入input里
        double total = 0;
        for (Map.Entry<String, TransactionOutput> item : UTXOs.entrySet()) {
            TransactionOutput UTXO = item.getValue();
            total += UTXO.value;
            inputs.add(new TransactionInput(UTXO.id));
            if (total > value) break;
        }

        //生成交易类
        Transaction newTransaction = new Transaction(publicKey, _recipient, value, inputs);
        newTransaction.generateSignature(privateKey);

        //将取出的output从wallet.UTXOs中删除
        for (TransactionInput input : inputs) {
            UTXOs.remove(input.transactionOutputId);
        }

        return newTransaction;
    }
}
